package com.pingan.haofang.searchcloud.api.query.parser.dbobject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.pingan.haofang.searchcloud.api.query.parser.dbobject.sqlnode.ColumnNode;

public class Condition implements Cloneable {

    protected String source;
    protected int index;
    protected ColumnNode left;
    protected Operator operator;
    protected List<SqlNode> rightList;
    protected int jdbcParamCount;

    public Condition() {
    }

    public Condition(int index, String source) {
        this.index = index;
        this.source = source;
    }

    public Condition(int index, ColumnNode left, Operator operator, SqlNode...right) {
        this.index = index;
        this.left = left;
        this.operator = operator;
        this.rightList = Arrays.asList(right);
        for (SqlNode node : right) {
            jdbcParamCount += node.getJdbcParamCount();
        }
    }

    /**
     * 是否为in(...)
     * 
     * @return
     */
    public boolean isInCondition() {
        return operator == Operator.EQ && rightList.size() > 1;
    }

    /**
     * 添加右值
     * 
     * @param node
     */
    public void addRightNode(SqlNode node) {
        if (rightList == null) {
            rightList = new ArrayList<SqlNode>();
        }
        rightList.add(node);
        jdbcParamCount += node.getJdbcParamCount();
    }

    public boolean execute(Object left) {
        for (SqlNode right : rightList) {
            if (operator.execute(left, right)) {
                return true;
            }
        }
        return false;
    }

    public void setRight(SqlNode node) {
        rightList = Arrays.asList(node);
        jdbcParamCount += node.getJdbcParamCount();
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public ColumnNode getLeft() {
        return left;
    }

    public void setLeft(ColumnNode left) {
        this.left = left;
    }

    public Operator getOperator() {
        return operator;
    }

    public void setOperator(Operator operator) {
        this.operator = operator;
    }

    public List<SqlNode> getRightList() {
        return rightList;
    }

    public void setRightList(List<SqlNode> rightList) {
        this.rightList = rightList;
        for (SqlNode node : rightList) {
            jdbcParamCount += node.getJdbcParamCount();
        }
    }
    
    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public int getJdbcParamCount() {
        return jdbcParamCount;
    }

    public SqlNode getRightOne() {
        return rightList.get(0);
    }

    @Override
    public String toString() {
        if (source != null) {
            return index + ":" + source;
        } else {
            return index + ":" + left + " " + operator + " " + StringUtils.join(rightList, ",");
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + jdbcParamCount;
        result = prime * result + ((left == null) ? 0 : left.hashCode());
        result = prime * result + ((operator == null) ? 0 : operator.hashCode());
        result = prime * result + ((rightList == null) ? 0 : rightList.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Condition other = (Condition) obj;
        if (jdbcParamCount != other.jdbcParamCount) {
            return false;
        }
        if (left == null) {
            if (other.left != null) {
                return false;
            }
        } else if (!left.equals(other.left)) {
            return false;
        }
        if (operator != other.operator) {
            return false;
        }
        if (rightList == null) {
            if (other.rightList != null) {
                return false;
            }
        } else if (!rightList.equals(other.rightList)) {
            return false;
        }
        return true;
    }

}
